package com.ocm.tourism.web;

import java.awt.Dimension;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.util.UriUtils;
import org.springframework.web.util.WebUtils;

import com.ocm.tourism.core.domain.Catalogues;
import com.ocm.tourism.core.domain.CataloguesFileInfo;
import com.ocm.tourism.core.domain.FileInfo;
import com.ocm.tourism.core.service.CataloguesService;
import com.ocm.tourism.file.MimeTypeSupport;
import com.ocm.tourism.file.SimpleImageInfo;
import com.ocm.tourism.web.util.FileInfoUtil;

@RequestMapping("/foodspecial")
@Controller
public class FoodSpecialController {

   @Autowired
   CataloguesService cataloguesService;

   @Autowired
   FileInfoUtil fileInfoUtil;

   @InitBinder
   public void initBinder(WebDataBinder binder) {
        binder.initDirectFieldAccess();
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
        dateFormat.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
    }

   @RequestMapping(value = "/create", method = RequestMethod.GET)
   public String createForm(Model uiModel) {
      Catalogues catalogues = new Catalogues();
      catalogues.setCataloguesType("foodspecial");
      populateEditForm(uiModel, catalogues);
      return "foodspecial/create";
   }

   @RequestMapping(value = "/{id}", method=RequestMethod.GET)
   public String show(@PathVariable("id") Long id, Model uiModel) {
      uiModel.addAttribute("itemId", id);
      CataloguesFileInfo actual = this.cataloguesService.findCataloguesFileInfos(id);
      populateEditForm(uiModel, actual);
      return "foodspecial/show";
   }

   @RequestMapping(value = "/{id}/update", method=RequestMethod.GET)
   public String showUpdate(@PathVariable("id") Long id, Model uiModel) {
      uiModel.addAttribute("itemId", id);
      CataloguesFileInfo actual = this.cataloguesService.findCataloguesFileInfos(id);
      populateEditForm(uiModel, actual);
      return "foodspecial/create";
   }

   @RequestMapping(value = "/{id}/detail", method=RequestMethod.GET)
   public String showDetail(@PathVariable("id") Long id, Model uiModel) {
      uiModel.addAttribute("itemId", id);
      CataloguesFileInfo actual = this.cataloguesService.findCataloguesFileInfos(id);
      populateEditForm(uiModel, actual);
      return "foodspecial/detail";
   }

   @RequestMapping(method = RequestMethod.POST)
   public String create(@Valid CataloguesFileInfo foodspecial, @RequestParam("fileData")CommonsMultipartFile commonsMultipartFile, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
      validate(commonsMultipartFile, uiModel, bindingResult);
      if (bindingResult.hasErrors()) {
         populateEditForm(uiModel, foodspecial);
         return "foodspecial/create";
      }
      if (commonsMultipartFile.getSize() > 0){
         String uploadDir = httpServletRequest.getSession().getServletContext().getInitParameter("uploadDir");
         String folderPath = fileInfoUtil.createContainer(uploadDir);
         FileInfo fileInfo = fileInfoUtil.writeFile(commonsMultipartFile, uploadDir, folderPath);
         foodspecial.setAvatar(fileInfo);
      }else{
         if (foodspecial.getId() != null){
            CataloguesFileInfo actual = this.cataloguesService.findCataloguesFileInfos(foodspecial.getId());
            if (actual != null){
               foodspecial.setAvatar(actual.getAvatar());
            }
         }
      }
      uiModel.asMap().clear();
      foodspecial.setCataloguesType("foodspecial");
      this.cataloguesService.saveCatalogues(foodspecial);
      return "redirect:/foodspecial?page=1&size=50";
   }
   
   @RequestMapping(value="/update", method = RequestMethod.POST)
   public String update(@Valid CataloguesFileInfo foodspecial, @RequestParam("fileData")CommonsMultipartFile commonsMultipartFile, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) throws Exception {
      validate(commonsMultipartFile, uiModel, bindingResult);
      if (bindingResult.hasErrors()) {
         populateEditForm(uiModel, foodspecial);
         return "foodspecial/create";
      }
      if (commonsMultipartFile.getSize() > 0){
         String uploadDir = httpServletRequest.getSession().getServletContext().getInitParameter("uploadDir");
         String folderPath = fileInfoUtil.createContainer(uploadDir);
         FileInfo fileInfo = fileInfoUtil.writeFile(commonsMultipartFile, uploadDir, folderPath);
         foodspecial.setAvatar(fileInfo);
      }else{
         CataloguesFileInfo actual = this.cataloguesService.findCataloguesFileInfos(foodspecial.getId());
         foodspecial.setAvatar(actual.getAvatar());
      }
      uiModel.asMap().clear();
      foodspecial.setCataloguesType("foodspecial");
      cataloguesService.saveCatalogues(foodspecial);
      return "redirect:/foodspecial/" + encodeUrlPathSegment(foodspecial.getId().toString(), httpServletRequest);
   }
   
   @RequestMapping(produces = "text/html", method=RequestMethod.GET)
   public String list(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel) {
       long count = cataloguesService.countFoodSpecials();
       if (page != null || size != null) {
           int sizeNo = size == null ? 10 : size.intValue();
           final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
           uiModel.addAttribute("foodspecials", cataloguesService.findFoodSpecials(firstResult, sizeNo));
           float nrOfPages = (float) count / sizeNo;
           uiModel.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
       } else {
           List<CataloguesFileInfo> foodspecials =  count == 0 ? new ArrayList<CataloguesFileInfo>() : cataloguesService.findFoodSpecials(0, 25);
           uiModel.addAttribute("foodspecials", foodspecials);
       }
       return "foodspecial/list";
   }

   @RequestMapping(value="/advs", produces = "text/html", method=RequestMethod.GET)
   public String listAdvs(@RequestParam(value = "periodTime", required = false) Integer periodTime, @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, Model uiModel) {
      long count = cataloguesService.countFoodSpecials();
      if (page != null || size != null) {
          int sizeNo = size == null ? 10 : size.intValue();
          final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
          uiModel.addAttribute("foodspecials", cataloguesService.findFoodSpecials(firstResult, sizeNo));
          float nrOfPages = (float) count / sizeNo;
          uiModel.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
      } else {
          List<CataloguesFileInfo> foodspecials =  count == 0 ? new ArrayList<CataloguesFileInfo>() : cataloguesService.findFoodSpecials(0, 25);
          uiModel.addAttribute("foodspecials", foodspecials);
      }
      return "foodspecial/advs";
   }

   void populateEditForm(Model uiModel, Catalogues foodspecial) {
      uiModel.addAttribute("foodspecial", foodspecial);
   }

   void validate(CommonsMultipartFile commonsMultipartFile,Model uiModel, Errors errors) throws IOException{
      if (commonsMultipartFile.getSize() > 0){
         InputStream inputStream = commonsMultipartFile.getInputStream();
         if (!MimeTypeSupport.supportMineType(commonsMultipartFile.getContentType())){
            errors.reject("error_fileData_contenttype");
         }
         if (commonsMultipartFile.getSize() > FileInfoUtil.DEFAULT_BUFFER_SIZE){
            errors.reject("error_fileData_large");
         }
         if (!errors.hasFieldErrors("fileData")){
            Dimension dimension = SimpleImageInfo.processStream(inputStream);
            if (dimension.getWidth() < 200){
               errors.reject("error_fileData_limit_width");
            }
         }
      }
   }
   
   String encodeUrlPathSegment(String pathSegment, HttpServletRequest httpServletRequest) {
      String enc = httpServletRequest.getCharacterEncoding();
      if (enc == null) {
          enc = WebUtils.DEFAULT_CHARACTER_ENCODING;
      }
      try {
          pathSegment = UriUtils.encodePathSegment(pathSegment, enc);
      } catch (UnsupportedEncodingException uee) {}
      return pathSegment;
  }
}
